package gui.mainFrame.testCreator;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import testGenerator.Controller;
import testGenerator.testMethodModel.AvailableTestMethods;
import testGenerator.testMethodModel.GenericTestPoint;
import testGenerator.testMethodModel.TestMethod;

/**
 *
 * @author William Whitney
 */
public class GenericTestPointEditor extends JPanel
{
    private static final long serialVersionUID = 1L;

    private ArrayList<GenericTestPoint> genericTestPoints;
    private final ArrayList<JTextField> leftSide;
    private final ArrayList<JTextField> rightSide;
    private final ArrayList<JComboBox> methodDropdown;

    /**
     * Default constructor.
     * @param controller
     */
    public GenericTestPointEditor(Controller controller)
    {
        this.genericTestPoints = controller.getGenericTestPoints();
        this.leftSide = new ArrayList<JTextField>();
        this.rightSide = new ArrayList<JTextField>();
        this.methodDropdown = new ArrayList<JComboBox>();

        //Setup panel
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        //Restore test points
        restoreView();
    }

    private void restoreView()
    {
        for (GenericTestPoint point : genericTestPoints)
        {
            this.add(getGUIEditorForTestPoint(point));
        }
        this.updateUI();
    }

    public void addTestPoint()
    {
        GenericTestPoint testPt = new GenericTestPoint();
        this.genericTestPoints.add(testPt);
        this.add(getGUIEditorForTestPoint(testPt));
        this.updateUI();
    }

    public void deleteTestPoint()
    {
        int numTestPoints = genericTestPoints.size();
        if (numTestPoints > 0)
        {
            genericTestPoints.remove(numTestPoints -1);
            this.remove(this.getComponent(numTestPoints - 1));
            this.updateUI();
        }
    }

    public void saveTestPoints()
    {

        for (int i = 0; i < this.genericTestPoints.size(); i++)
        {
            GenericTestPoint testPt = this.genericTestPoints.get(i);
            testPt.instanceManipulation = rightSide.get(i).getText();
            testPt.expectedResult = leftSide.get(i).getText();
            testPt.chosenMethod = (TestMethod) methodDropdown.get(i).getSelectedItem();
        }
    }
    
    private ActionListener getTestMethodChangedListener()
    {
        return new ActionListener()
        {

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                for (int i=0; i<methodDropdown.size(); i++) 
                {
                    if ( ((TestMethod)methodDropdown.get(i).getSelectedItem()).isAllowsTwoArgs() )
                    {
                        leftSide.get(i).setVisible(true);
                    }
                    else 
                    {
                        leftSide.get(i).setVisible(false);
                    }
                }
            }
            
        };
    }

    private JPanel getGUIEditorForTestPoint(GenericTestPoint testPt)
    {
        //Add return value
        JPanel testPoints = new JPanel();
        //Set layout
        FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
        testPoints.setLayout(layout);

        JComboBox chosenMethod = new JComboBox(AvailableTestMethods.getAvailableMethods().toArray());
        chosenMethod.addActionListener(getTestMethodChangedListener());
        methodDropdown.add(chosenMethod);
        testPoints.add(chosenMethod);
        
        //Part 1
        JLabel label = new JLabel("(");
        testPoints.add(label);

        //Part 2
        JTextField leftPortion = new JTextField(12);
        leftSide.add(leftPortion);
        leftPortion.setText(testPt.expectedResult);
        testPoints.add(leftPortion);

        //Part 3
        label = new JLabel(", instance.");
        testPoints.add(label);

        //Part 4
        JTextField rightPortion = new JTextField(12);
        rightSide.add(rightPortion);
        rightPortion.setText(testPt.instanceManipulation);
        testPoints.add(rightPortion);

        //Part 5
        label = new JLabel(");");
        testPoints.add(label);


        return testPoints;
    }
}
